#pragma once
#include <string>
#include <map>
#include <memory>
#include <nlohmann/json.hpp>
namespace cpp_backend
{
    namespace framework
    {
        enum class HttpStatus
        {
            // 2xx Success - The action was successfully received, understood, and accepted
            OK = 200,         ///< The request has succeeded
            CREATED = 201,    ///< The request has been fulfilled and resulted in a new resource being created
            NO_CONTENT = 204, ///< The server has fulfilled the request but does not need to return an entity-body

            // 4xx Client Error - The request contains bad syntax or cannot be fulfilled
            BAD_REQUEST = 400,  ///< The request could not be understood by the server due to malformed syntax
            UNAUTHORIZED = 401, ///< The request requires user authentication
            FORBIDDEN = 403,    ///< The server understood the request, but is refusing to fulfill it
            NOT_FOUND = 404,    ///< The server has not found anything matching the Request-URI
            CONFLICT = 409,     ///< The request could not be completed due to a conflict with the current state of the resource

            // 5xx Server Error - The server failed to fulfill an apparently valid request
            INTERNAL_SERVER_ERROR = 500, ///< The server encountered an unexpected condition which prevented it from fulfilling the request
            SERVICE_UNAVAILABLE = 503,   ///< The server is currently unable to handle the request due to a temporary overloading or maintenance of the server
        };
        /**
         * @brief 业务错误码
         */
        /**
         * @brief 业务错误码
         */
        enum class ErrorCode
        {
            SUCCESS = 0,
            INVALID_PARAM = 1001,
            USER_NOT_FOUND = 1002,
            USER_ALREADY_EXISTS = 1003,
            WRONG_PASSWORD = 1004,
            TOKEN_EXPIRED = 1005,
            TOKEN_INVALID = 1006,
            PERMISSION_DENIED = 1007,
            FILE_NOT_FOUND = 2001,
            FILE_TOO_LARGE = 2002,
            QUOTA_EXCEEDED = 2003,
            UPLOAD_FAILED = 2004,
            DOWNLOAD_FAILED = 2005,
            DATABASE_ERROR = 3001,
            REDIS_ERROR = 3002,
            SERVICE_NOT_FOUND = 3003,
            
            INTERNAL_ERROR = 9999,
        };
        /**
         * @brief 统一响应对象
         */
        class Response
        {
        public:
            explicit Response() : http_status_(HttpStatus::OK), error_code_(ErrorCode::SUCCESS)
            {
            }
            Response(ErrorCode code) : http_status_(HttpStatus::OK), error_code_(code)
            {
            }
            Response(HttpStatus status, ErrorCode code) : http_status_(status), error_code_(code)
            {
            }
            ~Response() = default;
            /**
             * @brief 设置HTTP状态码
             */
            void SetHttpStatus(HttpStatus status)
            {
                http_status_ = status;
            }
            HttpStatus GetHttpStatus() const
            {
                return http_status_;
            }
            int GetHttpStatusCode() const
            {
                return static_cast<int>(http_status_);
            }
            /**
             * @brief 设置业务错误码
             */
            void SetErrorCode(ErrorCode code)
            {
                error_code_ = code;
            }
            ErrorCode GetErrorCode() const
            {
                return error_code_;
            }
            int GetErrorCodeValue() const
            {
                return static_cast<int>(error_code_);
            }
            /**
             * @brief 设置错误消息
             */
            void SetMessage(const std::string &message)
            {
                message_ = message;
            }
            const std::string &GetMessage() const
            {
                return message_;
            }
            /**
             * @brief 设置响应数据
             */
            void SetData(const nlohmann::json &data)
            {
                data_ = data;
            }
            const nlohmann::json &GetData() const
            {
                return data_;
            }
            /**
             * @brief 设置响应头
             */
            void SetHeader(const std::string &key, const std::string &value)
            {
                headers_[key] = value;
            }
            const std::map<std::string, std::string> &GetHeaders() const
            {
                return headers_;
            }
            /**
             * @brief 设置原始响应体（二进制，用于文件下载）
             */
            void SetRawBody(const std::vector<uint8_t> &raw_body)
            {
                raw_body_ = raw_body;
            }
            const std::vector<uint8_t> &GetRawBody() const
            {
                return raw_body_;
            }
            /**
             * @brief 是否成功
             */
            bool IsSuccess() const
            {
                return error_code_ == ErrorCode::SUCCESS;
            }
            /**
             * @brief 转换为JSON对象
             */
            nlohmann::json ToJson() const
            {
                nlohmann::json j;
                j["code"] = static_cast<int>(error_code_);
                j["message"] = message_.empty() ? GetDefaultMessage() : message_;
                if (!data_.is_null())
                {
                    j["data"] = data_;
                }
                return j;
            }
            /**
             * @brief 转换为JSON字符串
             */
            std::string ToString() const
            {
                return ToJson().dump();
            }
            /**
             * @brief 创建成功响应
             */
            static Response Success(const nlohmann::json &data = nlohmann::json())
            {
                Response resp(ErrorCode::SUCCESS);
                resp.SetMessage("success");
                if (!data.is_null())
                {
                    resp.SetData(data);
                }
                return resp;
            }
            static Response Error(ErrorCode code, const std::string &message = "")
            {
                Response resp(code);
                resp.SetHttpStatus(GetHttpStatusByErrorCode(code));
                resp.SetMessage(message.empty() ? GetErrorMessage(code) : message);
                return resp;
            }
            /**
             * @brief 创建带HTTP状态码的错误响应
             */
            static Response Error(HttpStatus status, ErrorCode code, const std::string &message = "")
            {
                Response resp(status, code);
                resp.SetMessage(message.empty() ? GetErrorMessage(code) : message);
                return resp;
            }

        private:
            /**
             * @brief 获取默认消息
             */
            std::string GetDefaultMessage() const
            {
                return error_code_ == ErrorCode::SUCCESS ? "success" : "error";
            }
            /**
             * @brief 根据错误码获取默认错误消息
             */
            static std::string GetErrorMessage(ErrorCode code)
            {
                switch (code)
                {
                case ErrorCode::SUCCESS:
                    return "success";
                case ErrorCode::INVALID_PARAM:
                    return "invalid parameter";
                case ErrorCode::USER_NOT_FOUND:
                    return "user not found";
                case ErrorCode::USER_ALREADY_EXISTS:
                    return "user already exists";
                case ErrorCode::WRONG_PASSWORD:
                    return "wrong password";
                case ErrorCode::TOKEN_EXPIRED:
                    return "token expired";
                case ErrorCode::TOKEN_INVALID:
                    return "token invalid";
                case ErrorCode::PERMISSION_DENIED:
                    return "permission denied";
                case ErrorCode::FILE_NOT_FOUND:
                    return "file not found";
                case ErrorCode::FILE_TOO_LARGE:
                    return "file too large";
                case ErrorCode::QUOTA_EXCEEDED:
                    return "quota exceeded";
                case ErrorCode::UPLOAD_FAILED:
                    return "upload failed";
                case ErrorCode::DOWNLOAD_FAILED:
                    return "download failed";
                case ErrorCode::DATABASE_ERROR:
                    return "database error";
                case ErrorCode::REDIS_ERROR:
                    return "redis error";
                case ErrorCode::INTERNAL_ERROR:
                    return "internal error";
                case ErrorCode::SERVICE_NOT_FOUND:
                    return "service not found";
                default:
                    return "unknown error";
                }
            }
            /**
             * @brief 根据错误码获取HTTP状态码
             */
            static HttpStatus GetHttpStatusByErrorCode(ErrorCode code)
            {
                switch (code)
                {
                case ErrorCode::SUCCESS:
                    return HttpStatus::OK;
                case ErrorCode::INVALID_PARAM:
                    return HttpStatus::BAD_REQUEST;
                case ErrorCode::USER_NOT_FOUND:
                case ErrorCode::FILE_NOT_FOUND:
                    return HttpStatus::NOT_FOUND;
                case ErrorCode::USER_ALREADY_EXISTS:
                    return HttpStatus::CONFLICT;
                case ErrorCode::TOKEN_EXPIRED:
                case ErrorCode::TOKEN_INVALID:
                    return HttpStatus::UNAUTHORIZED;
                case ErrorCode::PERMISSION_DENIED:
                    return HttpStatus::FORBIDDEN;
                case ErrorCode::DATABASE_ERROR:
                case ErrorCode::REDIS_ERROR:
                case ErrorCode::INTERNAL_ERROR:
                    return HttpStatus::INTERNAL_SERVER_ERROR;
                case ErrorCode::SERVICE_NOT_FOUND:
                    return HttpStatus::SERVICE_UNAVAILABLE;
                default:
                    return HttpStatus::INTERNAL_SERVER_ERROR;
                }
            }

        private:
            HttpStatus http_status_;                     // HTTP 状态码
            ErrorCode error_code_;                       // 错误码
            std::string message_;                        // 错误消息
            nlohmann::json data_;                        // 响应数据
            std::map<std::string, std::string> headers_; // 响应头
            std::vector<uint8_t> raw_body_;              // 原始响应体（二进制）
        };
        using ResponsePtr = std::shared_ptr<Response>;
    }
}